home *** CD-ROM | disk | FTP | other *** search
/ Amiga Games Extra 1996 September / Amiga Games Extra CD-ROM 9-1996.iso / userbox / publicdomain / vim-4.2 / src / linefunc.c < prev    next >
C/C++ Source or Header  |  1996-06-09  |  3KB  |  170 lines

  1. /* vi:set ts=4 sw=4:
  2.  *
  3.  * VIM - Vi IMproved        by Bram Moolenaar
  4.  *
  5.  * Do ":help uganda"  in Vim to read copying and usage conditions.
  6.  * Do ":help credits" in Vim to see a list of people who contributed.
  7.  */
  8.  
  9. /*
  10.  * linefunc.c: some functions to move to the next/previous line and
  11.  *               to the next/previous character
  12.  */
  13.  
  14. #include "vim.h"
  15. #include "globals.h"
  16. #include "proto.h"
  17.  
  18. /*
  19.  * coladvance(col)
  20.  *
  21.  * Try to advance the Cursor to the specified column.
  22.  *
  23.  * return OK if desired column is reached, FAIL if not
  24.  */
  25.  
  26.     int
  27. coladvance(wcol)
  28.     colnr_t         wcol;
  29. {
  30.     int                 idx;
  31.     register char_u        *ptr;
  32.     register colnr_t    col;
  33.  
  34.     ptr = ml_get_curline();
  35.  
  36.     /* try to advance to the specified column */
  37.     idx = -1;
  38.     col = 0;
  39.     while (col <= wcol && *ptr)
  40.     {
  41.         ++idx;
  42.         /* Count a tab for what it's worth (if list mode not on) */
  43.         col += lbr_chartabsize(ptr, col);
  44.         ++ptr;
  45.     }
  46.     /*
  47.      * in insert mode it is allowed to be one char beyond the end of the line
  48.      */
  49.     if ((State & INSERT) && col <= wcol)
  50.         ++idx;
  51.     if (idx < 0)
  52.         curwin->w_cursor.col = 0;
  53.     else
  54.         curwin->w_cursor.col = idx;
  55.     if (col <= wcol)
  56.         return FAIL;        /* Couldn't reach column */
  57.     else
  58.         return OK;            /* Reached column */
  59. }
  60.  
  61. /*
  62.  * inc(p)
  63.  *
  64.  * Increment the line pointer 'p' crossing line boundaries as necessary.
  65.  * Return 1 when crossing a line, -1 when at end of file, 0 otherwise.
  66.  */
  67.     int
  68. inc_cursor()
  69. {
  70.     return inc(&curwin->w_cursor);
  71. }
  72.  
  73.     int
  74. inc(lp)
  75.     register FPOS  *lp;
  76. {
  77.     register char_u  *p = ml_get_pos(lp);
  78.  
  79.     if (*p != NUL)        /* still within line, move to next char (may be NUL) */
  80.     {
  81.         lp->col++;
  82.         return ((p[1] != NUL) ? 0 : 1);
  83.     }
  84.     if (lp->lnum != curbuf->b_ml.ml_line_count)        /* there is a next line */
  85.     {
  86.         lp->col = 0;
  87.         lp->lnum++;
  88.         return 1;
  89.     }
  90.     return -1;
  91. }
  92.  
  93. /*
  94.  * incl(lp): same as inc(), but skip the NUL at the end of non-empty lines
  95.  */
  96.     int
  97. incl(lp)
  98.     register FPOS *lp;
  99. {
  100.     register int r;
  101.  
  102.     if ((r = inc(lp)) == 1 && lp->col)
  103.         r = inc(lp);
  104.     return r;
  105. }
  106.  
  107. /*
  108.  * dec(p)
  109.  *
  110.  * Decrement the line pointer 'p' crossing line boundaries as necessary.
  111.  * Return 1 when crossing a line, -1 when at start of file, 0 otherwise.
  112.  */
  113.     int
  114. dec_cursor()
  115. {
  116.     return dec(&curwin->w_cursor);
  117. }
  118.  
  119.     int
  120. dec(lp)
  121.     register FPOS  *lp;
  122. {
  123.     if (lp->col > 0)
  124.     {            /* still within line */
  125.         lp->col--;
  126.         return 0;
  127.     }
  128.     if (lp->lnum > 1)
  129.     {            /* there is a prior line */
  130.         lp->lnum--;
  131.         lp->col = STRLEN(ml_get(lp->lnum));
  132.         return 1;
  133.     }
  134.     return -1;                    /* at start of file */
  135. }
  136.  
  137. /*
  138.  * decl(lp): same as dec(), but skip the NUL at the end of non-empty lines
  139.  */
  140.     int
  141. decl(lp)
  142.     register FPOS *lp;
  143. {
  144.     register int r;
  145.  
  146.     if ((r = dec(lp)) == 1 && lp->col)
  147.         r = dec(lp);
  148.     return r;
  149. }
  150.  
  151. /*
  152.  * make sure curwin->w_cursor in on a valid character
  153.  */
  154.     void
  155. adjust_cursor()
  156. {
  157.     colnr_t len;
  158.  
  159.     if (curwin->w_cursor.lnum == 0)
  160.         curwin->w_cursor.lnum = 1;
  161.     if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count)
  162.         curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
  163.  
  164.     len = STRLEN(ml_get_curline());
  165.     if (len == 0)
  166.         curwin->w_cursor.col = 0;
  167.     else if (curwin->w_cursor.col >= len)
  168.         curwin->w_cursor.col = len - 1;
  169. }
  170.